import math

import numpy as np
# import pandas as pd
# from main import scan_D, find_frequent_1_itemsets, scan_D_t, apriori_gen
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori

bcc_df = pd.read_csv('BCHAIN-MKPRU.csv')
bcc_lis = np.array(bcc_df['Value']).tolist()

gold_df = pd.read_csv('LBMA-GOLD.csv')
gold_lis = np.array(gold_df['USD (PM)']).tolist()


# print(bcc_lis)


def average_Ptn(n, p, t):
    # 2.1
    sum = 0
    for i in range(n):
        sum += p[t - i]
    return sum / n


def cal_x_mn_1t(average_Ptm, average_Ptn):
    # 2.2
    return math.log((average_Ptm / average_Ptn), math.e)


# 定义模糊集
W = 0.01


def miu_PS_set(x_mn_1t, W):
    # 2.3 定义正小PS模糊集
    if (0 <= x_mn_1t >= 2 * W):
        return 1 - abs(x_mn_1t - W) / W
    else:
        return 0


def miu_PS_set(x_mn_1t):
    # W = 0.01
    # 2.3 定义正小PS模糊集
    if (0 <= x_mn_1t >= 2 * W):
        return 1 - abs(x_mn_1t - W) / W
    else:
        return 0


def miu_PM_set(x_mn_1t, W):
    # 定义正中等PM模糊集
    if (W < x_mn_1t < 3 * W):
        return 1 - abs(x_mn_1t - 2 * W) / W
    else:
        return 0


def miu_PM_set(x_mn_1t):
    # W = 0.01
    # 定义正中等PM模糊集
    if (W < x_mn_1t < 3 * W):
        return 1 - abs(x_mn_1t - 2 * W) / W
    else:
        return 0


def miu_PL_set(x_mn_1t, W):
    # 2.4 定义PL模糊集
    if (x_mn_1t < 2 * W):
        return 0
    if (2 * W < x_mn_1t < 3 * W):
        return (x_mn_1t - 2 * W) / W
    if (x_mn_1t > 3 * W):
        return 1


def miu_PL_set(x_mn_1t):
    # W = 0.01
    # 2.4 定义PL模糊集
    if (x_mn_1t < 2 * W):
        return 0
    if (2 * W < x_mn_1t < 3 * W):
        return (x_mn_1t - 2 * W) / W
    if (x_mn_1t > 3 * W):
        return 1


def miu_NS_set(x_nm_1t, W):
    # 定义负小NS模糊集
    if ((0 - 2 * W) < x_nm_1t < 0):
        return 1 - abs(x_nm_1t + W) / W
    else:
        return 0


def miu_NS_set(x_nm_1t):
    # W = 0.01
    # 定义负小NS模糊集
    if ((0 - 2 * W) < x_nm_1t < 0):
        return 1 - abs(x_nm_1t + W) / W
    else:
        return 0


def miu_AZ_set(x_nm_1t, W):
    # 定义正中等AZ模糊集
    if ((0 - W) < x_nm_1t < W):
        return 1 - abs(x_nm_1t) / W
    else:
        return 0


def miu_AZ_set(x_nm_1t):
    # W = 0.01
    # 定义正中等AZ模糊集
    if ((0 - W) < x_nm_1t < W):
        return 1 - abs(x_nm_1t) / W
    else:
        return 0


def miu_NM_set(x_nm_1t, W):
    # 定义负中等NM模糊集
    if ((0 - 3 * W) < x_nm_1t < (0 - W)):
        return 1 - abs(x_nm_1t + 2 * W) / W
    else:
        return 0


def miu_NM_set(x_nm_1t):
    # W = 0.01
    # 定义负中等NM模糊集
    if ((0 - 3 * W) < x_nm_1t < (0 - W)):
        return 1 - abs(x_nm_1t + 2 * W) / W
    else:
        return 0


def miu_NL_set(x_mn_1t, W):
    # 2.4 定义NL模糊集
    if (x_mn_1t < (- 3 * W)):
        return 1
    if ((- 3 * W) < x_mn_1t < (- 2 * W)):
        return (x_mn_1t + 2 * W) / W
    if (x_mn_1t > (- 2 * W)):
        return 0


def miu_NL_set(x_mn_1t):
    # W = 0.01
    # 2.4 定义NL模糊集
    if (x_mn_1t < (- 3 * W)):
        return 1
    if ((- 3 * W) < x_mn_1t < (- 2 * W)):
        return (x_mn_1t + 2 * W) / W
    if (x_mn_1t > (- 2 * W)):
        return 0


# ===========定义模糊集============#


# 定义买卖信号模糊集
def miu_BB(ed):
    # 2.5
    if (ed < 0.2):
        return 0
    elif (0.2 < ed < 0.4):
        return (ed - 0.2) / 0.2
    else:
        return 1


def miu_SB(ed):
    if (ed < (- 0.4)):
        return 1
    elif ((- 0.4) < ed < (- 0.2)):
        return (- 5 * ed) - 1
    else:
        return 0


def miu_SM(ed):
    if ((- 0.4) < ed < (- 0.2)):
        return 5 * ed + 2
    elif ((- 0.2) < ed < (- 0.1)):
        return 1 - abs(0.2 + ed) / 0.1
    else:
        return 0


def miu_SS(ed):
    if ((- 0.2) < ed < 0):
        return 1 - abs(0.1 + ed) / 0.1
    else:
        return 0


def miu_N(ed):
    if ((- 0.1) < ed < 0.1):
        return 1 - abs(ed) / 0.1
    else:
        return 0


def miu_BS(ed):
    if (0 < ed < 0.2):
        return 1 - abs(0.1 - ed) / 0.1
    else:
        return 0


def miu_BM(ed):
    if (0.1 < ed < 0.2):
        return 1 - abs(0.2 - ed) / 0.1
    elif (0.2 < ed < 0.4):
        return (- 5 * ed) + 2
    else:
        return 0


def signal(list_):
    # 标记大于零的位置，起始位为1
    # 剔除隶属度小于等于0的模糊集
    list_return = []
    for i in range(14):
        if (list_[i] > 0):
            list_return.append(i + 1)
    return list_return


def Sign(list_):
    list_returns = []
    for i in list_:
        list_return = []
        lA = i[0:6]
        lA_max = lA.index(max(lA)) + 1
        lB = i[7:13]
        lB_max = lB.index(max(lB)) + 8
        list_return.append(lA_max)
        list_return.append(lB_max)
        list_returns.append(list_return)
    return list_returns


def For_(bcc_lis, tt):
    list_return = []
    for t in range(tt):
        Ptn = average_Ptn(20, bcc_lis, t)
        Ptm = average_Ptn(10, bcc_lis, t)
        # print("ptn1:", Ptn)
        # print("ptm1:", Ptm)
        x_mn_1t = cal_x_mn_1t(Ptm, Ptn)
        # print("cal_x_mn_1t(Ptm1, Ptn1):", cal_x_mn_1t(Ptm, Ptn))
        ps = miu_PS_set(x_mn_1t)
        pm = miu_PM_set(x_mn_1t)
        pl = miu_PL_set(x_mn_1t)
        ns = miu_NS_set(x_mn_1t)
        nm = miu_NM_set(x_mn_1t)
        nl = miu_NL_set(x_mn_1t)
        az = miu_AZ_set(x_mn_1t)
        list_A = [ps, pm, pl, ns, nm, nl, az]
        # print("list_A: ps, pm, pl, ns, nm, nl, az\n", list_A)

        Ptn = average_Ptn(20, bcc_lis, t + 1)
        Ptm = average_Ptn(10, bcc_lis, t + 1)
        # print("ptn2:", Ptn)
        # print("ptm2:", Ptm)
        ed = cal_x_mn_1t(Ptm, Ptn)
        # print("cal_x_mn_1t(Ptm2, Ptn2):", cal_x_mn_1t(Ptm, Ptn))
        # BS, BM, BB, SS, SM, SB, N
        BS, BM, BB, SS, SM, SB, N = miu_BS(ed), miu_BM(ed), miu_BB(ed), miu_SS(ed), miu_SM(ed), miu_SB(ed), miu_N(ed)
        list_ed = [BS, BM, BB, SS, SM, SB, N]
        # print("list_ed: BS, BM, BB, SS, SM, SB, N\n", list_ed)
        list_B = [ps, pm, pl, ns, nm, nl, az, BS, BM, BB, SS, SM, SB, N]
        # print(signal(list_B))
        # list_return.append(signal(list_B))
        list_return.append(list_B)
    return list_return


def For_A(bcc_lis, tt):
    list_return = []
    for t in range(tt):
        Ptn = average_Ptn(20, bcc_lis, t)
        Ptm = average_Ptn(10, bcc_lis, t)
        # print("ptn1:", Ptn)
        # print("ptm1:", Ptm)
        x_mn_1t = cal_x_mn_1t(Ptm, Ptn)
        # print("cal_x_mn_1t(Ptm1, Ptn1):", cal_x_mn_1t(Ptm, Ptn))
        ps = miu_PS_set(x_mn_1t)
        pm = miu_PM_set(x_mn_1t)
        pl = miu_PL_set(x_mn_1t)
        ns = miu_NS_set(x_mn_1t)
        nm = miu_NM_set(x_mn_1t)
        nl = miu_NL_set(x_mn_1t)
        az = miu_AZ_set(x_mn_1t)
        list_A = [ps, pm, pl, ns, nm, nl, az]
        # print("list_A: ps, pm, pl, ns, nm, nl, az\n", list_A)

        Ptn = average_Ptn(20, bcc_lis, t + 1)
        Ptm = average_Ptn(10, bcc_lis, t + 1)
        # print("ptn2:", Ptn)
        # print("ptm2:", Ptm)
        ed = cal_x_mn_1t(Ptm, Ptn)
        # print("cal_x_mn_1t(Ptm2, Ptn2):", cal_x_mn_1t(Ptm, Ptn))
        # BS, BM, BB, SS, SM, SB, N
        BS, BM, BB, SS, SM, SB, N = miu_BS(ed), miu_BM(ed), miu_BB(ed), miu_SS(ed), miu_SM(ed), miu_SB(ed), miu_N(ed)
        list_ed = [BS, BM, BB, SS, SM, SB, N]
        # print("list_ed: BS, BM, BB, SS, SM, SB, N\n", list_ed)
        list_B = [ps, pm, pl, ns, nm, nl, az, BS, BM, BB, SS, SM, SB, N]
        # print(signal(list_B))
        list_return.append(signal(list_B))
        print(type(list_B))
        # df=pd.DataFrame(list_B,columns=['ps','pm','pl','ns','nm','nl','az','BS','BM','BB','SS','SM','SB','N'])
        # df.to_excel('隶属度.xlsx')

    return list_return


def Apriori_sklearn(bcc_lis):
    data = For_A(bcc_lis, len(bcc_lis) - 1)
    # 这个地方 len(bcc_lis) - 1 的时间是比特币的最长的时间  最近的

    print(data)

    te = TransactionEncoder()
    # 进行 one-hot 编码
    te_ary = te.fit(data).transform(data)
    df = pd.DataFrame(te_ary, columns=te.columns_)

    # 利用Apriori找出频繁项集
    freq = apriori(df, min_support=0.3, use_colnames=True)


if __name__ == '__main__':
    data_bitcoin = For_(bcc_lis, len(bcc_lis) - 1)

    print("Sign(data_bitcoin):", Sign(data_bitcoin))
    print("len(data_bitcoin):", len(data_bitcoin))

    data_bitcoin_A = For_A(bcc_lis, len(bcc_lis) - 1)
    # 这个地方 len(bcc_lis) - 1 的时间是比特币的最长的时间  最近的
    d = []
    # print(data)
    te = TransactionEncoder()
    # 进行 one-hot 编码
    te_ary = te.fit(data_bitcoin_A).transform(data_bitcoin_A)
    df = pd.DataFrame(te_ary, columns=te.columns_)
    # 利用Apriori找出频繁项集
    freq = apriori(df, min_support=0.1, use_colnames=True)
    print("Apriori找出data_bitcoin_A频繁项集", freq)

    data_gold = For_(gold_lis, len(gold_lis) - 1)

    # print("Sign(data_gold):", Sign(data_gold))
    # print("len(data_gold):", len(data_gold))

    data_gold_A = For_A(gold_lis, len(gold_lis) - 1)
    # 这个地方 len(bcc_lis) - 1 的时间是比特币的最长的时间  最近的
    d = []
    # print(data)
    te = TransactionEncoder()
    # 进行 one-hot 编码
    te_ary = te.fit(data_gold_A).transform(data_gold_A)
    df = pd.DataFrame(te_ary, columns=te.columns_)
    # 利用Apriori找出频繁项集
    freq = apriori(df, min_support=0.1, use_colnames=True)
    print("Apriori找出data_gold_A频繁项集", freq)
